package com.lizhivscaomei.cleanduplicatefiles.cmd;

import com.alibaba.fastjson.JSON;
import com.lizhivscaomei.cleanduplicatefiles.cmd.pojo.Config;
import com.lizhivscaomei.cleanduplicatefiles.cmd.pojo.ConfigItem;
import com.lizhivscaomei.cleanduplicatefiles.cmd.pojo.Result;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ResourceLoader;
import org.springframework.shell.standard.ShellComponent;
import org.springframework.shell.standard.ShellMethod;
import org.springframework.shell.standard.ShellOption;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

/**
 * @author lizhi
 */
@ShellComponent
public class CleanDupFileCmds {

    @Autowired
    ResourceLoader resourceLoader;

    @Autowired
    FileTask fileTask;

    @ShellMethod("生成配置文件")
    public String gencfg() throws IOException {
        ConfigFile configFile = new ConfigFile();
        Config config = new Config();
        ConfigItem inConfigItem=new ConfigItem();
        inConfigItem.setDirs(new String[]{"扫描根路径","F://video"});
        inConfigItem.setExt(new String[]{"扩展名，例如",".doc",".ppt"});
        config.setInclude(inConfigItem);
        ConfigItem exConfigItem=new ConfigItem();
        exConfigItem.setDirs(new String[]{"扫描根路径","F://video"});
        exConfigItem.setExt(new String[]{"扩展名，例如",".doc",".ppt"});
        config.setExclude(exConfigItem);
        configFile.setConfig(config);
        File targetFile = new File("./config.json");
        FileUtils.writeStringToFile(targetFile, JSON.toJSONString(configFile), "UTF-8");
        if (targetFile.exists()) {
            return "success" + targetFile.getAbsolutePath();
        } else {
            return "failed";
        }
    }

    @ShellMethod("扫描，并生成结果")
    public void scan(@ShellOption(value = {"-F", "-f", "--file"}, defaultValue = "config.json") String configFile) {
        try {
            ConfigFile config = this.validateCfg(configFile);
            System.out.println("scanning...");
            Arrays.stream(config.getConfig().getInclude().getDirs()).forEach(path -> {
                this.handleScan(config, new File(path));
            });
            System.out.println("scan result:" + config.getMatchFiles().size());
            config.getMatchFiles().forEach((file, aBoolean) -> this.fileTask.dealFile(config, file));
        } catch (IOException e) {
        }
    }

    private void handleScan(ConfigFile config, File file) {
        if (file.exists()) {
            if (file.isDirectory()) {
                if (null == config.getConfig().getExclude().getDirs() || Arrays.stream(config.getConfig().getExclude().getDirs()).filter(exclude -> file.getAbsolutePath().contains(exclude)).count() == 0) {
                    //不再排除路径
                    Arrays.stream(file.listFiles()).forEach(child -> handleScan(config, child));
                }
            } else {
                if (Arrays.stream(config.getConfig().getInclude().getExt()).filter(ext -> file.getName().contains(ext)).count() > 0) {
                    //找到匹配的文件
                    config.getMatchFiles().put(file, false);
                }
            }
        }

    }


    private ConfigFile validateCfg(String configFile) throws IOException {
        File cfgFile = new File(configFile);
        if (cfgFile.exists()) {
            ConfigFile cfg = JSON.parseObject(FileUtils.readFileToString(cfgFile,"UTF-8"), ConfigFile.class);
            return cfg;
        } else {
            throw new IOException("not found config file");
        }

    }

    @ShellMethod("清除重复文件")
    public String clean(@ShellOption(value = {"-F", "-f", "--file"}, defaultValue = "result.json") String configFile) {
        try {
            List<Result> resultList = this.resultConfig(configFile);
            resultList.stream().forEach(result -> {
                result.getDelete().stream().forEach(path -> {
                    try {
                        File fileTemp = new File(path);
                        if (fileTemp.exists()) {
                            FileUtils.forceDelete(fileTemp);
                        }
                        System.out.println("complete:" + path);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                });
            });
        } catch (IOException e) {
            e.printStackTrace();
        }

        return "finished";
    }

    private List<Result> resultConfig(String configFile) throws IOException {
        File cfgFile = new File(configFile);
        if (cfgFile.exists()) {
            List<Result> cfg = JSON.parseArray(FileUtils.readFileToString(cfgFile,"UTF-8"), Result.class);
            return cfg;
        } else {
            throw new IOException("not found config file");
        }

    }
}
